#include "crossdevice.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/time.h>
#include "iup.h"
#include "iup_config.h"

#include "device.h"
#include "util.h"
#include "DelayCall.h"
#include "SysTick.h"




struct GlobalStruct{
	Ihandle* iupVal_tbar;
};

struct GlobalStruct global_value = {NULL};

void setTbarValue(int value)
{
#ifdef ENABLE_DEBUG_TBAR
	char valueStr[8];
	sprintf(valueStr, "%d", value);
	IupSetAttribute(global_value.iupVal_tbar, "VALUE", valueStr);
#endif
}


int write_file(const char* filename, const char* str, int count)
{
  FILE* file = fopen(filename, "w");
  if (!file)
  {
    IupMessagef("Error", "Can't open file: %s", filename);
    return 0;
  }
  printf("write |%s| len = %d\n", str, count);
  fwrite(str, 1, count, file);

  if (ferror(file))
    IupMessagef("Error", "Fail when writing to file: %s", filename);

  fclose(file);
  return 1;
}

char* read_file(const char* filename, int *size)
{
  char* str;
  FILE* file = fopen(filename, "rb");
  if (!file)
  {
    IupMessagef("Error", "Can't open file: %s", filename);
	*size = 0;
    return NULL;
  }

  /* calculate file size */
  fseek(file, 0, SEEK_END);
  *size = ftell(file);
  fseek(file, 0, SEEK_SET);

  /* allocate memory for the file contents + nul terminator */
  str = (char*)malloc((*size) + 1);
  /* read all data at once */
  fread(str, *size, 1, file);
  /* set the nul terminator */
  str[*size] = 0;

  if (ferror(file))
  {
    IupMessagef("Error", "Fail when reading from file: %s", filename);
	*size=0;
	fclose(file);
	free(str);
	return NULL;
  }

  fclose(file);
  return str;
}

/////////////////////////////////// open com ///////////////////////////////////////



int item_exit_action_cb(Ihandle* item_exit)
{
  Ihandle* dlg = IupGetDialog(item_exit);
  Ihandle* config = (Ihandle*)IupGetAttribute(dlg, "CONFIG");

  close_device();

  IupConfigDialogClosed(config, dlg, "MainWindow");
  IupConfigSave(config);
  IupDestroy(config);
  return IUP_CLOSE;
}

int com_list_action(Ihandle *ih, char *text, int item, int state)
{
    printf("text=%s, item=%d, state=%d\n ", text, item, state);
	return IUP_DEFAULT;
}

Ihandle *open_timer_handle = NULL;

int log_on = 0;

int log_toggle_action(Ihandle* ih, int state)
{
	if(state)
	{
		log_on = 1;
		printf("log on\r\n");
	}
	else
	{
		log_on = 0;
		printf("log off\r\n");
	}
	
	return IUP_DEFAULT;
}

void open_timer_set_handle(Ihandle *ih)
{
	open_timer_handle = ih;
}

void append_str_to_multitext(char *str)
{
	Ihandle *multitext = IupGetDialogChild(open_timer_handle, "MULTITEXT");
	IupSetAttribute(multitext, "APPEND", str);
}

int open_timer_action(Ihandle *ih)
{
	static int isStart = 0;
	static char * preDestIP = NULL;
	static char buffer[2048]; // 大约网络包的最大值
	
	if(isStart)
	{
		return IUP_DEFAULT;
	}
	isStart = 1;
	
	if(ptr_device)
	{
		
		int len = 0;
		char *remoteIP;
		
		Ihandle *multitext = IupGetDialogChild(open_timer_handle, "MULTITEXT");
		len = ptr_device->readBuf(buffer, sizeof(buffer)-1);
		
		buffer[len] = '\0';
		//sprintf(buffer, "test");
		//len = strlen(buffer);
		//printf("read len = %d\n", len);
		if(len > 0)
		{
			Ihandle* mode_list = IupGetDialogChild(open_timer_handle, "MODE");
			char *modeStr = IupGetAttribute(mode_list, "VALUE"); 
			remoteIP = ptr_device->getRemoteIP();

			device_receive_buffer((BYTE*)buffer, len);
			printf("read len = %d\n", len);
			len = processBuffer(buffer, len);
			printf("processBuffer len = %d\n", len);
			
			if(remoteIP != NULL)
			{
				if(preDestIP == NULL)
				{
					preDestIP = (char*)malloc(24);
					sprintf(preDestIP, "\n[%s]:\n", remoteIP);
					IupSetAttribute(multitext, "APPEND", preDestIP);
				}
				else
				{
					if(!strstr(preDestIP, remoteIP))
					{
						sprintf(preDestIP, "\n[%s]:\n", remoteIP);
						IupSetAttribute(multitext, "APPEND", preDestIP);
					}
				}
			}
			
			if(strstr(modeStr, "1")) // ascii
			{
				if(log_on)
				{
					char *buf = log(buffer);
					IupSetAttribute(multitext, "APPEND", buf);
					free(buf);
				}
				else
				{
					IupSetAttribute(multitext, "APPEND", buffer);
				}
			}
			else  // hex
			{
				char *display_buf = charStringToHexString(buffer, len);
				
				if(log_on)
				{
					char *buf = log(display_buf);
					IupSetAttribute(multitext, "APPEND", buf);
					free(buf);
				}
				else
				{
					IupSetAttribute(multitext, "APPEND", display_buf);
				}
				free(display_buf);
			}
			#if DEBUG_UART_1
			printf("read:%s\n", buffer);
			#endif
		}
		if(ih != NULL)
		{
			isStart = 0;
			device_task();
		}
	}
	isStart = 0;
	
	return IUP_DEFAULT;
}



int open_button_action(Ihandle* ih)
{
	char * title = IupGetAttribute(ih, "TITLE");
	char * comName, *baudStr, *parityStr;
	Ihandle * timer = (Ihandle*)IupGetAttribute(ih, "OPEN_TIMER");
	Ihandle* com_list = IupGetDialogChild(ih, "COM");
	Ihandle* baud_list = IupGetDialogChild(ih, "BAUD");
	Ihandle* parity_list = IupGetDialogChild(ih, "PARITY");
	
	comName = IupGetAttribute(com_list, "VALUE");
	baudStr = IupGetAttribute(baud_list, "VALUE"); 
	parityStr = IupGetAttribute(parity_list, "VALUE"); 
	
	if(strstr(title, "Open"))
	{
		#if DEBUG_UART_1
		printf("open %s\n", comName);
		#endif
		int speed = atoi(baudStr);
		char parity = 'n';
		if(strstr(parityStr, "ODD"))
		{
			parity = 'o';
		}
		else if(strstr(parityStr, "EVEN"))
		{
			parity = 'e';
		}
		
		
		
		if(!open_device(comName, speed, parity))
		{
			IupMessagef("Error", "Can't open %s. It is used by another app!", comName);
			return IUP_DEFAULT;
		}
		open_timer_set_handle(ih);
		IupSetAttribute(timer, "TIME", "10");
		SysDelay1ms(10);
		IupSetAttribute(timer, "RUN", "YES");
		IupSetCallback(timer, "ACTION_CB", (Icallback) open_timer_action);
		
		IupSetAttribute(ih, "TITLE", "Close");
		IupSetAttribute(com_list, "ACTIVE", "No");
		IupSetAttribute(baud_list, "ACTIVE", "No");
	}
	else
	{
		#if DEBUG_UART_1
		printf("close %s\n", comName);
		#endif
		IupSetAttribute(timer, "RUN", "NO");
		
		
		close_device();
		IupSetAttribute(ih, "TITLE", "Open");
		IupSetAttribute(com_list, "ACTIVE", "Yes");
		IupSetAttribute(baud_list, "ACTIVE", "Yes");
		
	}
	return IUP_DEFAULT;
}

int clear_button_action(Ihandle* ih)
{
	Ihandle* multitext = IupGetDialogChild(ih, "MULTITEXT");
	IupSetAttribute(multitext, "VALUE", "");
	
	return IUP_DEFAULT;
	
}

int save_button_action(Ihandle* ih)
{
	
	Ihandle *filedlg;
	

	filedlg = IupFileDlg();
	IupSetAttribute(filedlg, "DIALOGTYPE", "SAVE");
	IupSetAttribute(filedlg, "EXTFILTER", "Text Files|*.txt|All Files|*.*|");
	IupSetAttributeHandle(filedlg, "PARENTDIALOG", IupGetDialog(ih));

	IupPopup(filedlg, IUP_CENTERPARENT, IUP_CENTERPARENT);
	if (IupGetInt(filedlg, "STATUS") != -1)
	{
		char* filename = IupGetAttribute(filedlg, "VALUE");
		Ihandle* multitext = IupGetDialogChild(ih, "MULTITEXT");
		char* value = IupGetAttribute(multitext, "VALUE");
		int count = strlen(value);
		write_file(filename, value, count);
		printf("save file %s\n", filename);
	}

	IupDestroy(filedlg);
	return IUP_DEFAULT;
}

int receive_mode_list_action(Ihandle *ih, char *text, int item, int state)
{
	Ihandle* multitext = IupGetDialogChild(ih, "MULTITEXT");
	char * value = IupGetAttribute(multitext, "VALUE");
	if((item==2) && (state == 1))
	{
		// hex mode
		char *buf = charStringToHexString(value, strlen(value));
		IupSetAttribute(multitext, "VALUE", buf);
		free(buf);
		
	}
	else if((item==1) && (state == 1))
	{
		// ascii mode
		int len;
		char *buf = hexStringToCharString(value, &len);
		IupSetAttribute(multitext, "VALUE", buf);
		printf("%s len=%d\n", buf, len);
		free(buf);
	}
	//printf("item=%d, state=%d\n", item, state);
	return IUP_DEFAULT;
}

Ihandle * create_hbox_open(void)
{
	char indexName[10];
	int index=1;
    Ihandle *hbox, *btn_open, *btn_clear, *com_list, *baud_list, *parity_list, *mode_list, *btn_save, *log_toggle;
    
	Ihandle *timer = IupTimer();
	
    btn_open = IupButton(NULL, NULL);
    IupSetAttribute(btn_open, "TITLE", "Open");
    IupSetAttribute(btn_open, "CANFOCUS", "No");
	IupSetAttribute(btn_open, "OPEN_TIMER", (char*)timer);
    //IupSetAttribute(btn_open, "FLAT", "Yes");
	IupSetCallback( btn_open, "ACTION", (Icallback) open_button_action );
    
    btn_clear = IupButton(NULL, NULL);
    IupSetAttribute(btn_clear, "TITLE", "Clear");
    IupSetAttribute(btn_clear, "CANFOCUS", "No");
    //IupSetAttribute(btn_clear, "FLAT", "Yes");
	IupSetCallback( btn_clear, "ACTION", (Icallback) clear_button_action );
    
    com_list = IupList( NULL);
    IupSetAttribute(com_list,"DROPDOWN","YES");
	IupSetAttribute(com_list,"VALUE","COM");
    //IupSetAttribute(com_list,"1","COM1");
    //IupSetAttribute(com_list,"2","COM2");
    //IupSetAttribute(com_list,"3","COM3");
    
	
	
    {
        CrossDeviceList* list = CrossDevice::getDeviceList();
		if(list)
		{
			
			CrossDeviceList* next = list;
			while(next)
			{
				printf("%s\n", next->name);
				sprintf(indexName, "%d", index++);
				IupSetAttribute(com_list, indexName , next->name);
				printf("add %s %s\n", indexName, next->name);
				
				next = next->next;
			}
		}
    }
	IupSetAttribute(com_list,"CINDEX","1");
    IupSetAttribute(com_list,"CX","10");
    IupSetAttribute(com_list,"CY","10");
	IupSetAttribute(com_list, "NAME", "COM");
	IupSetAttribute(com_list, "EDITBOX", "Yes"); 
	
	baud_list = IupList( NULL);
    IupSetAttribute(baud_list,"DROPDOWN","YES");
    IupSetAttribute(baud_list,"VALUE","1");
    IupSetAttribute(baud_list,"1","115200");
    IupSetAttribute(baud_list,"2","57600");
    IupSetAttribute(baud_list,"3","38400");
	IupSetAttribute(baud_list,"4","19200");
	IupSetAttribute(baud_list,"5","9600");
    IupSetAttribute(baud_list,"CINDEX","1");
    IupSetAttribute(baud_list,"CX","10");
    IupSetAttribute(baud_list,"CY","10");
	IupSetAttribute(baud_list, "NAME", "BAUD");
	IupSetAttribute(baud_list, "EDITBOX", "Yes"); 

	parity_list = IupList( NULL);
    IupSetAttribute(parity_list,"DROPDOWN","YES");
    IupSetAttribute(parity_list,"VALUE","1");
    IupSetAttribute(parity_list,"1","NONE");
    IupSetAttribute(parity_list,"2","ODD");
    IupSetAttribute(parity_list,"3","EVEN");
    IupSetAttribute(parity_list,"CINDEX","1");
    IupSetAttribute(parity_list,"CX","10");
    IupSetAttribute(parity_list,"CY","10");
	IupSetAttribute(parity_list, "NAME", "PARITY");
	IupSetAttribute(parity_list, "EDITBOX", "No"); 
	//IupSetCallback( baud_list, "ACTION", (Icallback) com_list_action );
	
	mode_list = IupList( NULL);
    IupSetAttribute(mode_list,"DROPDOWN","YES");
    IupSetAttribute(mode_list,"VALUE","1");
    IupSetAttribute(mode_list,"1","ASCII");
    IupSetAttribute(mode_list,"2","HEX");
    IupSetAttribute(mode_list,"CINDEX","1");
    IupSetAttribute(mode_list,"CX","10");
    IupSetAttribute(mode_list,"CY","10");
	IupSetAttribute(mode_list, "NAME", "MODE");
	IupSetCallback(mode_list, "ACTION", (Icallback) receive_mode_list_action);
	
	
	btn_save = IupButton(NULL, NULL);
    IupSetAttribute(btn_save, "TITLE", "Save");
    IupSetAttribute(btn_save, "CANFOCUS", "No");
    //IupSetAttribute(btn_open, "FLAT", "Yes");
	IupSetCallback( btn_save, "ACTION", (Icallback) save_button_action );
	
	log_toggle = IupToggle("log", "no");
	IupSetCallback( log_toggle, "ACTION", (Icallback) log_toggle_action );
	
    
    //hbox = IupHbox(btn_open, com_list, baud_list, mode_list, log_toggle, btn_clear, btn_save, NULL);
	hbox = IupHbox(btn_open, com_list, baud_list, parity_list, mode_list, log_toggle, btn_clear, btn_save, NULL);
    
    IupSetAttribute(hbox, "MARGIN", "5x5");
    IupSetAttribute(hbox, "GAP", "8");
	
	return hbox;
}

/////////////////////////////////////// send txt //////////////////////////////
int send_button_action(Ihandle* ih)
{
	
	Ihandle* tabs = IupGetDialogChild(ih, "SEND_TAB");
	Ihandle* multitext =(Ihandle*) IupGetAttribute(tabs,"VALUE_HANDLE");
	Ihandle* mode_list = IupGetDialogChild(ih, "SEND_MODE");
	char * value = IupGetAttribute(multitext, "VALUE");
	char * sendModeStr = IupGetAttribute(mode_list, "VALUE"); 
	int len = strlen(value);
	printf("mode = %s\n", sendModeStr);
	if((ptr_device)&&(len>0))
	{
		if(strstr(sendModeStr, "1")) 
		{
			// ascii mode
			device_send_str(value, len);
			#if DEBUG_UART_1
			printf("write %s = %d\n", value, len);
			#endif
		}
		else
		{
			// hex mode
			
			int index = 0;
			char *buf = hexStringToCharString(value, &index);
			device_writeBuf((char*)buf, index);
			#if DEBUG_UART_1
			printf("write hex = %d\n", index);
			#endif
			
			
			free(buf);
		}
		#if DEBUG_UART_1
		printf("send:%s, %s\n", value, sendModeStr);
		#endif
	}
	else
	{
		#if DEBUG_UART_1
		printf("send button click\n");
		#endif
	}
	
	
	
	
	return IUP_DEFAULT;
}

Ihandle * auto_handle = NULL;

void send_set_handle(Ihandle* ih)
{
	auto_handle = ih;
}
void auto_send_set_handle(Ihandle* ih)
{
	auto_handle = ih;
}

int timer_auto_send_action(Ihandle *ih)
{
	send_button_action(auto_handle);
	return IUP_DEFAULT;
}

int auto_toggle_action(Ihandle* ih, int state)
{
	Ihandle * timer = (Ihandle*)IupGetAttribute(ih, "TIMER");
	Ihandle * ms_text = IupGetDialogChild(ih, "MS_TEXT");
	
	if(state)
	{
		
		Ihandle * ms_text = IupGetDialogChild(ih, "MS_TEXT");
		char * ms_time_str = IupGetAttribute(ms_text, "VALUE");		
		send_set_handle(ih);
		IupSetAttribute(timer, "TIME", ms_time_str);
		IupSetAttribute(timer, "RUN", "YES");
		IupSetCallback(timer, "ACTION_CB", (Icallback) timer_auto_send_action);
		IupSetAttribute(ms_text, "ACTIVE", "NO");
		printf("auto send on\r\n");
	}
	else
	{
		IupSetAttribute(timer, "RUN", "NO");
		IupSetAttribute(ms_text, "ACTIVE", "YES");
		printf("auto send off\r\n");
	}
	
	return IUP_DEFAULT;
}

int clear_send_text_button_action(Ihandle* ih)
{
	Ihandle* tabs = IupGetDialogChild(ih, "SEND_TAB");
	Ihandle* multitext =(Ihandle*) IupGetAttribute(tabs,"VALUE_HANDLE");
	
	//Ihandle* multitext = IupGetDialogChild(ih, "SEND_MULTITEXT");

	
	IupSetAttribute(multitext, "VALUE", "");
	return IUP_DEFAULT;
}

int mode_list_action(Ihandle *ih, char *text, int item, int state)
{
	Ihandle* tabs = IupGetDialogChild(ih, "SEND_TAB");
	Ihandle* multitext =(Ihandle*) IupGetAttribute(tabs,"VALUE_HANDLE");
	char * value = IupGetAttribute(multitext, "VALUE");
	if((item==2) && (state == 1))
	{
		// hex mode
		char *buf = charStringToHexString(value, strlen(value));
		IupSetAttribute(multitext, "VALUE", buf);
		free(buf);
		
	}
	else if((item==1) && (state == 1))
	{
		// ascii mode
		int len;
		char *buf = hexStringToCharString(value, &len);
		IupSetAttribute(multitext, "VALUE", buf);
		printf("%s len=%d\n", buf, len);
		free(buf);
	}
	//printf("item=%d, state=%d\n", item, state);
	return IUP_DEFAULT;
}

int open_txt_file_button_action(Ihandle* ih)
{
	
	Ihandle *filedlg;
	

	filedlg = IupFileDlg();
	IupSetAttribute(filedlg, "DIALOGTYPE", "OPEN");
	IupSetAttribute(filedlg, "EXTFILTER", "Text Files|*.txt|All Files|*.*|");
	IupSetAttributeHandle(filedlg, "PARENTDIALOG", IupGetDialog(ih));

	IupPopup(filedlg, IUP_CENTERPARENT, IUP_CENTERPARENT);
	if (IupGetInt(filedlg, "STATUS") != -1)
	{
		char* filename = IupGetAttribute(filedlg, "VALUE");
		Ihandle* tabs = IupGetDialogChild(ih, "SEND_TAB");
		Ihandle* multitext =(Ihandle*) IupGetAttribute(tabs,"VALUE_HANDLE");
		int size = 0;
		char * buf = read_file(filename, &size);
		if(size > 0)
		{
			IupSetAttribute(multitext, "VALUE", buf);
			free(buf);
		}
		
		printf("open txt file %s\n", filename);
	}

	IupDestroy(filedlg);
	
	
	return IUP_DEFAULT;
}

int open_bin_file_button_action(Ihandle* ih)
{
	
	Ihandle *filedlg;
	

	filedlg = IupFileDlg();
	IupSetAttribute(filedlg, "DIALOGTYPE", "OPEN");
	IupSetAttribute(filedlg, "EXTFILTER", "Bin Files|*.bin|All Files|*.*|");
	IupSetAttributeHandle(filedlg, "PARENTDIALOG", IupGetDialog(ih));

	IupPopup(filedlg, IUP_CENTERPARENT, IUP_CENTERPARENT);
	if (IupGetInt(filedlg, "STATUS") != -1)
	{
		char* filename = IupGetAttribute(filedlg, "VALUE");
		Ihandle* tabs = IupGetDialogChild(ih, "SEND_TAB");
		Ihandle* multitext =(Ihandle*) IupGetAttribute(tabs,"VALUE_HANDLE");
		int size = 0;
		char * buf = read_file(filename, &size);
		
		if(size > 0)
		{
			char * hexString = charStringToHexString(buf, size);
			IupSetAttribute(multitext, "VALUE", hexString);
			free(buf);
			free(hexString);
		}
		
		printf("open bin file %s\n", filename);
	}

	IupDestroy(filedlg);
	
	
	return IUP_DEFAULT;
}

int save_send_txt_button_action(Ihandle* ih)
{
	
	Ihandle *filedlg;
	

	filedlg = IupFileDlg();
	IupSetAttribute(filedlg, "DIALOGTYPE", "SAVE");
	IupSetAttribute(filedlg, "EXTFILTER", "Text Files|*.txt|All Files|*.*|");
	IupSetAttributeHandle(filedlg, "PARENTDIALOG", IupGetDialog(ih));

	IupPopup(filedlg, IUP_CENTERPARENT, IUP_CENTERPARENT);
	if (IupGetInt(filedlg, "STATUS") != -1)
	{
		char* filename = IupGetAttribute(filedlg, "VALUE");
		Ihandle* tabs = IupGetDialogChild(ih, "SEND_TAB");
		Ihandle* multitext =(Ihandle*) IupGetAttribute(tabs,"VALUE_HANDLE");
		char* value = IupGetAttribute(multitext, "VALUE");
		int count = strlen(value);
		write_file(filename, value, count);
		printf("save file %s\n", filename);
	}

	IupDestroy(filedlg);
	return IUP_DEFAULT;
}

Ihandle * create_hbox_send(void)
{
	Ihandle *hbox, *btn_send, *btn_clear, *mode_list, *ms_text, *ms_label, *auto_check, *timer, *btn_open_text, *btn_open_bin, *btn_save;
    
    btn_send = IupButton(NULL, NULL);
    IupSetAttribute(btn_send, "TITLE", "Send");
    IupSetAttribute(btn_send, "CANFOCUS", "No");
    //IupSetAttribute(btn_open, "FLAT", "Yes");
	IupSetCallback( btn_send, "ACTION", (Icallback) send_button_action );
	
	btn_clear = IupButton(NULL, NULL);
    IupSetAttribute(btn_clear, "TITLE", "Clear");
    IupSetAttribute(btn_clear, "CANFOCUS", "No");
    //IupSetAttribute(btn_open, "FLAT", "Yes");
	IupSetCallback( btn_clear, "ACTION", (Icallback) clear_send_text_button_action );
    
    
	
	mode_list = IupList( NULL);
    IupSetAttribute(mode_list,"DROPDOWN","YES");
    IupSetAttribute(mode_list,"VALUE","1");
    IupSetAttribute(mode_list,"1","ASCII");
    IupSetAttribute(mode_list,"2","HEX");
    IupSetAttribute(mode_list,"CINDEX","1");
    IupSetAttribute(mode_list,"CX","10");
    IupSetAttribute(mode_list,"CY","10");
	IupSetAttribute(mode_list, "NAME", "SEND_MODE");
	IupSetCallback(mode_list, "ACTION", (Icallback) mode_list_action);
	
	
	ms_text = IupText(NULL);
    IupSetAttribute(ms_text, "MULTILINE", "NO");
    IupSetAttribute(ms_text, "EXPAND", "NO");
    IupSetAttribute(ms_text, "NAME", "MS_TEXT");
    IupSetAttribute(ms_text, "DIRTY", "NO");
	IupSetAttribute(ms_text, "VALUE", "1000");
	IupSetAttribute(ms_text, "VISIBLECOLUMNS", "4");
	
	ms_label = IupLabel("ms");
    IupSetAttribute(ms_label, "NAME", "STATUSBAR");  
    IupSetAttribute(ms_label, "EXPAND", "NO");
	
	auto_check = IupToggle("Auto", "Manual");
	timer = IupTimer();
	IupSetCallback( auto_check, "ACTION", (Icallback) auto_toggle_action );
	IupSetAttribute(auto_check, "TIMER", (char*)timer);
	IupSetAttribute(auto_check, "NAME", "AUTO_CHECK");
	
	btn_open_text = IupButton(NULL, NULL);
    IupSetAttribute(btn_open_text, "TITLE", "Open TXT");
    IupSetAttribute(btn_open_text, "CANFOCUS", "No");
	IupSetCallback( btn_open_text, "ACTION", (Icallback) open_txt_file_button_action );
	
	btn_open_bin = IupButton(NULL, NULL);
    IupSetAttribute(btn_open_bin, "TITLE", "Open BIN");
    IupSetAttribute(btn_open_bin, "CANFOCUS", "No");
	IupSetCallback( btn_open_bin, "ACTION", (Icallback) open_bin_file_button_action );
	
	btn_save = IupButton(NULL, NULL);
    IupSetAttribute(btn_save, "TITLE", "Save");
    IupSetAttribute(btn_save, "CANFOCUS", "No");
	IupSetCallback( btn_save, "ACTION", (Icallback) save_send_txt_button_action );
	
	
    
    hbox = IupHbox(btn_send, mode_list, ms_text, ms_label, auto_check, btn_clear, btn_open_text, btn_open_bin, btn_save, NULL);
    
    IupSetAttribute(hbox, "MARGIN", "5x5");
    IupSetAttribute(hbox, "GAP", "8");
	
	return hbox;
}

/************************************* send cmd ****************************************/
int sendcmd_button_action(Ihandle* ih)
{
	char *adr_str, *cmd_str, *dat1_str, *dat2_str, *dat3_str, *dat4_str;
	Ihandle* adr_text = IupGetDialogChild(ih, "ADR_TEXT");
	Ihandle* cmd_text = IupGetDialogChild(ih, "CMD_TEXT");
	Ihandle* dat1_text = IupGetDialogChild(ih, "DAT1_TEXT");
	Ihandle* dat2_text = IupGetDialogChild(ih, "DAT2_TEXT");
	Ihandle* dat3_text = IupGetDialogChild(ih, "DAT3_TEXT");
	Ihandle* dat4_text = IupGetDialogChild(ih, "DAT4_TEXT");
	
	adr_str = IupGetAttribute(adr_text, "VALUE");
	cmd_str = IupGetAttribute(cmd_text, "VALUE");
	dat1_str = IupGetAttribute(dat1_text, "VALUE");
	dat2_str = IupGetAttribute(dat2_text, "VALUE");
	dat3_str = IupGetAttribute(dat3_text, "VALUE");
	dat4_str = IupGetAttribute(dat4_text, "VALUE");

	BYTE cmd = HexCharToByte(cmd_str);
	if(cmd == 0xf0)
	{
		char buffer[32];
		Ihandle* datablock_text = IupGetDialogChild(ih, "DATABLOCK_MULTITEXT");
		Ihandle* tabs = IupGetDialogChild(ih, "SEND_TAB");
		Ihandle* multitext =(Ihandle*) IupGetAttribute(tabs,"VALUE_HANDLE");
		char *datablock_str = IupGetAttribute(datablock_text, "VALUE");
		int len;
		char *datablock_byte = hexStringToCharString(datablock_str, &len);
		if(len != 0)
		{
			int i;
			BYTE checksum = 0;
			len = len+1;
			for(i=0; i<len-1; i++)
			{
				checksum += datablock_byte[i];
			}
			datablock_byte[len-1] = checksum;
		}
		BYTE adr = HexCharToByte(adr_str);
		BYTE dat1 = HexCharToByte(dat1_str);
		BYTE dat2 = HexCharToByte(dat2_str);
		BYTE dat3 = len;
		BYTE dat4 = len>>8;
		BYTE sn = 0;
		BYTE checksum = adr+sn+cmd+dat1+dat2+dat3+dat4;
		checksum &= 0xff;
		sprintf(buffer, "<T%02X%02X%02X%02X%02X%02X%02X%02X>",
                adr, sn, cmd, dat1, dat2, dat3, dat4, checksum);
		device_writeBuf(buffer, strlen(buffer));
		IupSetAttribute(multitext, "APPEND", buffer);
		if(len)
		{
			char *toHexChar = charStringToHexString(datablock_byte, len);
			device_writeBuf(datablock_byte, len);

			char *DisplayChar = (char*)malloc(strlen(toHexChar)+8);
			sprintf(DisplayChar, "[ %s ]", toHexChar);
			IupSetAttribute(multitext, "APPEND", DisplayChar);

			free(DisplayChar);
			free(toHexChar);
			
		}
		
		free(datablock_byte);
	}
	else
	{
		char buffer[32];
		Ihandle* tabs = IupGetDialogChild(ih, "SEND_TAB");
		Ihandle* multitext =(Ihandle*) IupGetAttribute(tabs,"VALUE_HANDLE");
		BYTE adr = HexCharToByte(adr_str);
		
		BYTE dat1 = HexCharToByte(dat1_str);
		BYTE dat2 = HexCharToByte(dat2_str);
		BYTE dat3 = HexCharToByte(dat3_str);
		BYTE dat4 = HexCharToByte(dat4_str);
		BYTE sn = 0;
		BYTE checksum = adr+sn+cmd+dat1+dat2+dat3+dat4;
        checksum &= 0xff;
        sprintf(buffer, "<T%02X%02X%02X%02X%02X%02X%02X%02X>",
                adr, sn, cmd, dat1, dat2, dat3, dat4, checksum);
		
		device_writeBuf(buffer, strlen(buffer));
		IupSetAttribute(multitext, "APPEND", buffer);
		if(cmd == 0xf2)
		{
			Ihandle* datablock_text = IupGetDialogChild(ih, "DATABLOCK_MULTITEXT");
			char *datablock_str = IupGetAttribute(datablock_text, "VALUE");
			device_writeBuf(datablock_str, strlen(datablock_str));
			IupSetAttribute(multitext, "APPEND", datablock_str);
		}
		
		
	}
	#if DEBUG_UART_1
	printf("send cmd %s, %s, %s, %s, %s, %s\n", adr_str, cmd_str, dat1_str, dat2_str, dat3_str, dat4_str);
	#endif
	
	return IUP_DEFAULT;
}

int mlaction(Ihandle *self, int c, char* after)
{  
	//if (c == 'g')    return IUP_IGNORE;  else    return IUP_DEFAULT;
	//printf("mlaction:%c, %s\n", c, after);
	if(iscntrl(c))
	{
		return IUP_DEFAULT;
	}
	if((strlen(after)>2)||(!isxdigit(c)))
	{
		return IUP_IGNORE;
	}
	
	return IUP_DEFAULT;
}

const char * send_mutitext_name_list[] = {
	"SEND_MULTITEXT0",
	"SEND_MULTITEXT1",
	"SEND_MULTITEXT2",
	"SEND_MULTITEXT3",
	"SEND_MULTITEXT4",
	"SEND_MULTITEXT5",
	"SEND_MULTITEXT6",
	"SEND_MULTITEXT7",
	
};

const char * get_send_mutitext_name(int value)
{
	if(value<0 || value>7)
	{
		return send_mutitext_name_list[0];
	}
	return send_mutitext_name_list[value];
}
Ihandle * create_send_mutitext_help(int value)
{
	Ihandle * send_multitext = IupText(NULL);
	const char * name = get_send_mutitext_name(value);
	
	char * tabName = (char*) malloc(8);
	sprintf(tabName, "Tab %d", value);
	IupSetAttribute(send_multitext, "MULTILINE", "YES");
    IupSetAttribute(send_multitext, "EXPAND", "YES");
    IupSetAttribute(send_multitext, "NAME", name);
    IupSetAttribute(send_multitext, "DIRTY", "NO");
	IupSetAttribute(send_multitext, "APPENDNEWLINE", "NO");
	IupSetAttribute(send_multitext, "WORDWRAP", "YES");
	IupSetAttribute(send_multitext, "TABTITLE", tabName);

	return send_multitext;
}

Ihandle * create_send_mutitext(void)
{
	Ihandle * tabs1; 
	Ihandle * send_multitext = create_send_mutitext_help(0);

	Ihandle * send_multitext1 = create_send_mutitext_help(1);

	Ihandle * send_multitext2 = create_send_mutitext_help(2);

	Ihandle * send_multitext3 = create_send_mutitext_help(3);

	Ihandle * send_multitext4 = create_send_mutitext_help(4);

	Ihandle * send_multitext5 = create_send_mutitext_help(5);

	Ihandle * send_multitext6 = create_send_mutitext_help(6);

	Ihandle * send_multitext7 = create_send_mutitext_help(7);

	tabs1 = IupTabs(send_multitext,send_multitext1,send_multitext2, 
		send_multitext3, send_multitext4, send_multitext5, send_multitext6, send_multitext7,
		(Ihandle *)NULL);


	
	//IupSetAttribute(tabs1, "HIGHCOLOR", "255 128 255");
	//IupSetAttribute(tabs1, "TABSFORECOLOR", "255 0 0");

	IupSetAttribute(tabs1, "NAME", "SEND_TAB");

	return tabs1;
}

Ihandle * create_hbox_sendcmd(void)
{
	Ihandle *hbox, *btn_send;
	Ihandle *adr_label, *adr_text, *cmd_label, *cmd_text, *dat1_label, *dat1_text;
	Ihandle *dat2_label, *dat2_text, *dat3_label, *dat3_text, *dat4_label, *dat4_text;
    
    btn_send = IupButton(NULL, NULL);
    IupSetAttribute(btn_send, "TITLE", "Send Cmd");
    IupSetAttribute(btn_send, "CANFOCUS", "No");
    //IupSetAttribute(btn_open, "FLAT", "Yes");
	IupSetCallback( btn_send, "ACTION", (Icallback) sendcmd_button_action );
    
    
	adr_label = IupLabel("adr"); 
	
	adr_text = IupText(NULL);
    IupSetAttribute(adr_text, "NAME", "ADR_TEXT");
	IupSetAttribute(adr_text, "VISIBLECOLUMNS", "2");
	IupSetAttribute(adr_text, "VALUE", "00");
	IupSetCallback(adr_text, "ACTION", (Icallback)mlaction);
	
	cmd_label = IupLabel("cmd"); 
	
	cmd_text = IupText(NULL);
    IupSetAttribute(cmd_text, "NAME", "CMD_TEXT");
	IupSetAttribute(cmd_text, "VISIBLECOLUMNS", "2");
	IupSetAttribute(cmd_text, "VALUE", "68");
	IupSetCallback(cmd_text, "ACTION", (Icallback)mlaction);
	
	dat1_label = IupLabel("dat1"); 
	
	dat1_text = IupText(NULL);
    IupSetAttribute(dat1_text, "NAME", "DAT1_TEXT");
	IupSetAttribute(dat1_text, "VISIBLECOLUMNS", "2");
	IupSetAttribute(dat1_text, "VALUE", "01");
	IupSetCallback(dat1_text, "ACTION", (Icallback)mlaction);
	
	dat2_label = IupLabel("dat2"); 
	
	dat2_text = IupText(NULL);
    IupSetAttribute(dat2_text, "NAME", "DAT2_TEXT");
	IupSetAttribute(dat2_text, "VISIBLECOLUMNS", "2");
	IupSetAttribute(dat2_text, "VALUE", "00");
	IupSetCallback(dat2_text, "ACTION", (Icallback)mlaction);
	
	dat3_label = IupLabel("dat3"); 
	
	dat3_text = IupText(NULL);
    IupSetAttribute(dat3_text, "NAME", "DAT3_TEXT");
	IupSetAttribute(dat3_text, "VISIBLECOLUMNS", "2");
	IupSetAttribute(dat3_text, "VALUE", "00");
	IupSetCallback(dat3_text, "ACTION", (Icallback)mlaction);
	
	dat4_label = IupLabel("dat4"); 
	
	dat4_text = IupText(NULL);
    IupSetAttribute(dat4_text, "NAME", "DAT4_TEXT");
	IupSetAttribute(dat4_text, "VISIBLECOLUMNS", "2");
	IupSetAttribute(dat4_text, "VALUE", "00");
	IupSetCallback(dat4_text, "ACTION", (Icallback)mlaction);
	
	
	
	
    
    hbox = IupHbox(btn_send, adr_label, adr_text, cmd_label, cmd_text, dat1_label, dat1_text, 
		dat2_label, dat2_text, dat3_label, dat3_text, dat4_label, dat4_text, NULL);
    
    IupSetAttribute(hbox, "MARGIN", "5x5");
    IupSetAttribute(hbox, "GAP", "8");
	
	return hbox;
}

/*************************************data block ***************************************/

Ihandle * create_hbox_datablock(void)
{
	Ihandle *hbox, *label_datablock, *text_datablock;
	
	label_datablock = IupLabel("data\nblock");
	
	text_datablock = IupText(NULL);
    IupSetAttribute(text_datablock, "MULTILINE", "YES");
    IupSetAttribute(text_datablock, "EXPAND", "YES");
    IupSetAttribute(text_datablock, "NAME", "DATABLOCK_MULTITEXT");
    IupSetAttribute(text_datablock, "DIRTY", "NO");
	IupSetAttribute(text_datablock, "APPENDNEWLINE", "NO");
	IupSetAttribute(text_datablock, "WORDWRAP", "YES");
	
	
	
	hbox = IupHbox(label_datablock, text_datablock,  NULL);
    
    IupSetAttribute(hbox, "MARGIN", "5x5");
    IupSetAttribute(hbox, "GAP", "8");
	
	//IupSetAttribute(hbox, "MAXSIZE", "65535x48");
	
	return hbox;
}

/************************************* send file ****************************************/

int sendfile_button_action(Ihandle* ih)
{
	Ihandle *filename_text = IupGetDialogChild(ih, "FILENAME_TEXT");
	char* filename = IupGetAttribute(filename_text, "VALUE");
	
	if(ptr_device && filename)
	{
		int size;
		char * buf = read_file(filename, &size);
		device_writeBuf(buf, size);		
		printf("send file size = %d\n", size);
		free(buf);
	}
	printf("send file: %s\n", filename);
	
	return IUP_DEFAULT;
}

int openfile_button_action(Ihandle* ih)
{
	
	Ihandle *filedlg;
	

	filedlg = IupFileDlg();
	IupSetAttribute(filedlg, "DIALOGTYPE", "OPEN");
	IupSetAttribute(filedlg, "EXTFILTER", "Text Files|*.txt|All Files|*.*|");
	IupSetAttributeHandle(filedlg, "PARENTDIALOG", IupGetDialog(ih));

	IupPopup(filedlg, IUP_CENTERPARENT, IUP_CENTERPARENT);
	if (IupGetInt(filedlg, "STATUS") != -1)
	{
		char* filename = IupGetAttribute(filedlg, "VALUE");
		Ihandle *filename_text = IupGetDialogChild(ih, "FILENAME_TEXT");
		IupSetAttribute(filename_text, "VALUE", filename);
		printf("open file %s\n", filename);
	}

	IupDestroy(filedlg);
	
	
	return IUP_DEFAULT;
}

Ihandle * create_hbox_sendfile(void)
{
	Ihandle *hbox, *btn_send;
	Ihandle *filename_text, *open_file_button;
	
	btn_send = IupButton(NULL, NULL);
    IupSetAttribute(btn_send, "TITLE", "Send File");
    IupSetAttribute(btn_send, "CANFOCUS", "No");
    //IupSetAttribute(btn_open, "FLAT", "Yes");
	IupSetCallback( btn_send, "ACTION", (Icallback) sendfile_button_action );
	
	
	filename_text = IupText(NULL);
    IupSetAttribute(filename_text, "MULTILINE", "NO");
    IupSetAttribute(filename_text, "EXPAND", "HORIZONTAL");
    IupSetAttribute(filename_text, "NAME", "FILENAME_TEXT");
	
	open_file_button = IupButton(NULL, NULL);
    IupSetAttribute(open_file_button, "TITLE", "Open File");
    IupSetAttribute(open_file_button, "CANFOCUS", "No");
    //IupSetAttribute(btn_open, "FLAT", "Yes");
	IupSetCallback( open_file_button, "ACTION", (Icallback) openfile_button_action );
	
	
	hbox = IupHbox(btn_send, filename_text, open_file_button, NULL);
    
    IupSetAttribute(hbox, "MARGIN", "5x5");
    IupSetAttribute(hbox, "GAP", "8");
	
	return hbox;
}

/******************************image*******************************/
static unsigned char pixmap_x [ ] = 
{
  1,2,3,3,3,3,3,3,3,2,1, 
  2,1,2,3,3,3,3,3,2,1,2, 
  3,2,1,2,3,3,3,2,1,2,3, 
  3,3,2,1,2,3,2,1,2,3,3, 
  3,3,3,2,1,2,1,2,3,3,3, 
  3,3,3,3,2,1,2,3,3,3,3, 
  3,3,3,2,1,2,1,2,3,3,3, 
  3,3,2,1,2,3,2,1,2,3,3, 
  3,2,1,2,3,3,3,2,1,2,3, 
  2,1,2,3,3,3,3,3,2,1,2, 
  1,2,3,3,3,3,3,3,3,2,1
}; 

#include "image_rc.c"

/********************************** Main *****************************************/


int main(int argc, char **argv)
{
  Ihandle *dlg, *multitext, *vbox, * send_multitext, *img_x, *img_rs232, *hbox, *iupVal_tbar;
  Ihandle *config;
  Ihandle *hbox_open, *hbox_send, *hbox_sendcmd, *hbox_sendfile;
  Ihandle *hbox_datablock;
  
  WORD socketVersion = MAKEWORD(2,2);
  WSADATA wsaData; 
  if(WSAStartup(socketVersion, &wsaData) != 0)
  {
    printf("err 1\n");
    return 1;
  }

  IupOpen(&argc, &argv);
  //IupImageLibOpen();
  
  img_x = IupImage ( 11, 11, pixmap_x );
  
  
  IupSetAttribute ( img_x, "1", "0 1 0");
  IupSetAttribute ( img_x, "2", "255 0 0"); 
  IupSetAttribute ( img_x, "3", "255 255 0");
  IupSetHandle ( "img_x", img_x );
  
  img_rs232 = IupImageRGBA(32, 32, gImage_rs232);
  IupSetHandle ( "img_rs232", img_rs232 );

  config = IupConfig();
  IupSetAttribute(config, "APP_NAME", "iup_rs232");
  IupConfigLoad(config);

  multitext = IupText(NULL);
    IupSetAttribute(multitext, "MULTILINE", "YES");
    IupSetAttribute(multitext, "EXPAND", "YES");
    IupSetAttribute(multitext, "NAME", "MULTITEXT");
    IupSetAttribute(multitext, "DIRTY", "NO");
	IupSetAttribute(multitext, "APPENDNEWLINE", "NO");
	IupSetAttribute(multitext, "WORDWRAP", "YES");

  
  hbox_open = create_hbox_open();
  
  hbox_send = create_hbox_send();
  
  

  send_multitext = create_send_mutitext();
	
  hbox_sendcmd = create_hbox_sendcmd();
  
  hbox_datablock = create_hbox_datablock();
  
  hbox_sendfile = create_hbox_sendfile();
  
  
	
  vbox = IupVbox(hbox_open, multitext, hbox_send, send_multitext, hbox_sendcmd, hbox_datablock, hbox_sendfile, NULL);
  
  IupSetAttribute(vbox, "MARGIN", "5x5");
  IupSetAttribute(vbox, "GAP", "2");
  

#ifdef   ENABLE_DEBUG_TBAR
  ////////////////// t-bar////////////////////
  iupVal_tbar = IupVal("VERTICAL");
  global_value.iupVal_tbar = iupVal_tbar;
  IupSetAttribute(iupVal_tbar, "MAX", "1024");
  IupSetAttribute(iupVal_tbar, "MIN", "0");
  ////////////////////////////////////////////
  
  hbox = IupHbox(vbox, iupVal_tbar, NULL);
#endif  
  
  
  
#ifdef ENABLE_DEBUG_TBAR
  dlg = IupDialog(hbox);
#else
  dlg = IupDialog(vbox);
#endif
  IupSetAttribute(dlg, "SIZE", "HALFxHALF");
  IupSetCallback(dlg, "CLOSE_CB", (Icallback)item_exit_action_cb);
  //IupSetCallback(dlg, "DROPFILES_CB", (Icallback)dropfiles_cb);

  IupSetAttribute(dlg, "CONFIG", (char*)config);
  IupSetAttribute(dlg, "ICON", "img_rs232");

  /* parent for pre-defined dialogs in closed functions (IupMessage) */
  IupSetAttributeHandle(NULL, "PARENTDIALOG", dlg);

  

  IupConfigDialogShow(config, dlg, "MainWindow");

  

 

  IupMainLoop();

  IupClose();
  
  WSACleanup();
  
  return EXIT_SUCCESS;
}